package org.gdpu.action;

import com.opensymphony.xwork2.ModelDriven;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.gdpu.base.PageView;
import org.gdpu.model.*;
import org.gdpu.service.*;
import org.gdpu.vo.BloodOrderVO;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Created with IntelliJ IDEA.
 * User: willson
 * Date: 13-11-8
 * Time: 下午3:40
 * To change this template use File | Settings | File Templates.
 */

@Component("orderBlood")
@Scope("prototype")
public class OrderBloodAction extends MyActionSupport implements ModelDriven<BloodOrderVO> {

    private final static Logger logger = LogManager.getLogger(OrderBloodAction.class);
    private final BloodOrderVO bloodOrderVO = new BloodOrderVO();
    private OfficeService officeService;
    private UserInfoService userInfoService;
    private BloodOrderService bloodOrderService;
    private BloodTypeService bloodTypeService;
    private BloodMatchService bloodMatchService;
    private BloodBankService bloodBankService;
    private BloodSumService bloodSumService;
    private BloodNameService bloodNameService;
    private final BloodOrder bloodOrder = new BloodOrder();

    //申请用血
    public String execute() throws Exception {
        if (bloodOrderVO.getBloodType().equals("#")) {
            bloodOrderVO.setResultMessage("请填写申请血型");
            return ERROR;
        }
        if (!IsDigital(bloodOrderVO.getBloodVolume())) {
            bloodOrderVO.setResultMessage("请正确填写申请用血量");
            return ERROR;
        }
        if (bloodOrderVO.getUser().equals("")) {
            bloodOrderVO.setResultMessage("请填写申请用血患者");
            return ERROR;
        }
        if (bloodOrderVO.getOfficeName().equals("#")) {
            bloodOrderVO.setResultMessage("请填写申请用血科室");
            return ERROR;
        }
        if (bloodOrderVO.getBloodName().equals("#")) {
            bloodOrderVO.setResultMessage("请填写申请使用血液类型");
            return ERROR;
        }
        //Todo:获取当前登录用户名等信息
        UserInfo userInfo = userInfoService.findPersonByUserName("doctor");
        Office office = officeService.findPersonByOfficeName(bloodOrderVO.getOfficeName());
        BloodType bloodType = bloodTypeService.findTypeName(bloodOrderVO.getBloodType());
        bloodOrder.setBloodVolume(Double.parseDouble(bloodOrderVO.getBloodVolume()));
        bloodOrder.setDoctorName(userInfo);
        bloodOrder.setOfficeName(office);
        bloodOrder.setUser(bloodOrderVO.getUser());
        bloodOrder.setState(0);
        bloodOrder.setApplyTime(new Date());
        bloodOrder.setBloodType(bloodType);
        bloodOrder.setBloodName(bloodNameService.findByName(bloodOrderVO.getBloodName()));
        try {
            bloodOrderService.save(bloodOrder);
            if (!match(bloodOrder.getApplyBloodId(), bloodOrder.getBloodVolume(), bloodType)) {
                bloodOrderService.delete(BloodOrder.class, bloodOrder.getApplyBloodId());
                bloodOrderVO.setResultMessage("该血型余量不足！请稍后再次提交申请！");
                return ERROR;
            }
            bloodOrderVO.setResultMessage("申请提交成功！");
            logger.trace("user:" + "doctor" + " apply " + bloodOrderVO.getBloodType() + " blood:" + bloodOrderVO.getBloodVolume() + "cc");
        } catch (Exception e) {
            logger.trace(e);
            bloodOrderVO.setResultMessage("填写申请有误！");
            return ERROR;
        }
        return SUCCESS;
    }

    public String notProvideBlood() {
        PageView<BloodOrder> pageView = bloodOrderService.findBloodOrder(bloodOrderVO);
        bloodOrderVO.setPageView(pageView);
        view = "/page/BloodIn/bloodOrderList.jsp";
        return VIEW;
    }

    public String provideBlood() {
        int[] applyBloodIds = bloodOrderVO.getApplyBloodIds();
        bloodOrderService.provide(applyBloodIds, bloodOrderVO.getMessage());
        bloodOrderVO.setResultMessage("操作成功！");
        return SUCCESS;
    }

    @Override
    public BloodOrderVO getModel() {
        return bloodOrderVO;
    }

    @Resource(name = "officeServiceImpl")
    public void setOfficeService(OfficeService officeService) {
        this.officeService = officeService;
    }

    @Resource(name = "userInfoServiceImpl")
    public void setUserInfoService(UserInfoService userInfoService) {
        this.userInfoService = userInfoService;
    }

    @Resource(name = "bloodOrderServiceImpl")
    public void setBloodOrderService(BloodOrderService bloodOrderService) {
        this.bloodOrderService = bloodOrderService;
    }

    @Resource(name = "bloodTypeServiceImpl")
    public void setBloodTypeService(BloodTypeService bloodTypeService) {
        this.bloodTypeService = bloodTypeService;
    }

    @Resource(name = "bloodMatchServiceImpl")
    public void setBloodMatchService(BloodMatchService bloodMatchService) {
        this.bloodMatchService = bloodMatchService;
    }

    @Resource(name = "bloodBankServiceImpl")
    public void setBloodBankService(BloodBankService bloodBankService) {
        this.bloodBankService = bloodBankService;
    }

    @Resource(name = "bloodSumServiceImpl")
    public void setBloodSumService(BloodSumService bloodSumService) {
        this.bloodSumService = bloodSumService;
    }

    @Resource(name = "bloodNameServiceImpl")
    public void setBloodNameService(BloodNameService bloodNameService) {
        this.bloodNameService = bloodNameService;
    }

    //判断输入字符串能否转为double类型
    private boolean IsDigital(String str) {
        Pattern pattern = Pattern.compile("-?[^\\D]+\\.?[^\\D]+");
        return pattern.matcher(str).matches();
    }

    //自动配血
    private boolean match(int applyBloodId, double bloodVolume, BloodType bloodType) {
        List<BloodBank> bloodBanks = bloodMatchService.findBloodBankByBloodVolume(bloodVolume, bloodType);
        if (bloodBanks.size() == 0)
            return false;

        BloodOrder order = bloodOrderService.find(BloodOrder.class, applyBloodId);

        for (BloodBank bloodBank : bloodBanks) {
            BloodMatch bloodMatch = new BloodMatch();
            bloodMatch.setBloodOrder(order);
            bloodMatch.setBloodBank(bloodBank);
            bloodMatchService.save(bloodMatch);
            bloodBank.setState(2);
            bloodBankService.update(bloodBank);
            bloodSumService.bloodVolume(bloodBank.getBloodType().getBloodType(), bloodBank.getBloodVolume(), false);
        }
        return true;
    }
}
